#!/usr/bin/env python
# -*- coding: utf-8 -*-
import gtk
import gobject

import form


class LayerRow(gobject.GObject):
    """A wrapper for putting layer objects on a gtk.ListStore.
    """
    type_spec = (gobject.TYPE_STRING,
                 gobject.TYPE_STRING,
                 gobject.TYPE_BOOLEAN,
                 gobject.TYPE_OBJECT)

    COL_NAME = 0
    COL_TYPE = 1
    COL_VISIBLE = 2
    COL_SELF = 3

    def __init__(self, layer):
        """Creates a layer row for the given layer.
	"""
        super(LayerRow, self).__init__()
        self.layer = layer

    def __getitem__(self, i):
        """Returns the layer info to show on each indexed column of
        the list store.
        """
        if i == 0:
            return self.layer.name
        elif i == 1:
            return str(type(self.layer))
        elif i == 2:
            return self.layer.visible
        elif i == 3:
            return self

    def __len__(self):
        """Number of cells on the row
        """
        return len(self.type_spec)

gobject.type_register(LayerRow)


class LayerTreeView(gtk.TreeView):
    """A TreeView based widget to show layer names and other stuff.
    """

    def __init__(self):
        """
	"""
        list_store = gtk.ListStore(*LayerRow.type_spec)
        super(LayerTreeView, self).__init__(list_store)

        self._make_text_column('Name', 0)
        self._make_text_column('Type', 1)

        self.set_reorderable(True)

    def add_layer(self, layer):
        """Adds a layer to the layer list.
        """
        store = self.get_model()
        store.append(LayerRow(layer))

    def _make_text_column(self, name, index):
        """
        """
        cell = gtk.CellRendererText()
        col = gtk.TreeViewColumn(name)
        col.pack_start(cell,True)
        col.add_attribute(cell, 'text', index)
        self.append_column(col)


class AddLayerDialog(gtk.Dialog):
    """Dialog for creating new layers.
    """

    def __init__(self, layer_types):
        """
	"""
        super(AddLayerDialog, self).__init__("New layer")

        hbox = gtk.HBox()

        hbox.pack_start(gtk.Label('Layer Type'))
        hbox.pack_start(form.ObjectListInput("objects", layer_types).widget)

        hbox.show_all()

        self.vbox.pack_end(hbox, True)
        self.connect('response', self.on_response)

    def _get_layer_types(self):
        """
        """
        self.combo = gtk.combo_box_new_text()
        for t in self.layer_list.layer_types:
            self.combo.append_text(t)

        return self.combo

    def on_response(self, dlg, id):
        if id == gtk.RESPONSE_OK:
            print "ok"


class LayerList(gtk.VBox):
    """This is the layer list widget to be used on the main interface.

    LayerList provides the toplevel UI element that will be used for
    layer management. Internally it is just a gtk.VBox that puts the
    needed widgets inside itself. But besides that, it also provide
    the interface that other parts of the program will use to acess
    the layers.
    """

    layer_types = []

    def __init__(self, layers=None):
        """
	"""
        super(LayerList, self).__init__()
        self.tree_view = LayerTreeView()
        self.pack_start(self.tree_view, True)

        button = gtk.Button(stock=gtk.STOCK_ADD)
        button.connect('clicked', self.on_add_layer)
        self.pack_start(button, False)

    def on_add_layer(self, btn):
        """Callback for click on add layer button.
        """
        dlg = AddLayerDialog(self.layer_types)
        dlg.run()

    def add_layer(self, layer):
        """Adds a layer to the layer list.
        """
        self.tree_view.add_layer(layer)

    def __iter__(self):
        """Iterator over the layers available.
        """
        return (row[LayerRow.COL_SELF].layer
                for row in iter(self.tree_view.get_model()))

    @property
    def current(self):
        model, iter = self.tree_view.get_selection().get_selected()
        if iter:
            layer_row = model.get_value(iter, 3)
            return layer_row.layer
        else:
            return None

    @classmethod
    def register_layer_type(cls, type):
        """Register a layer type that can be created with this layer
        list.
        """
        cls.layer_types.append(type)

